/* QtLua -- Lua bindings for Qt
   Copyright (C) 2011, Jarek Pelczar

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General
   Public License along with this library; if not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301 USA

*/

#include "qluascriptprogram.h"
#include <QSharedData>
#include <QTextCodec>
extern "C" {
#include "../etc/lua.hpp"
}

class QLuaScriptProgramData : public QSharedData
{
public:
    QString m_text;
    QByteArray m_byteCode;
    QLuaScriptProgram::ScriptType m_type;
    QString m_fileName;

    inline bool operator == (const QLuaScriptProgramData& other) const
    {
        if(m_type != other.m_type)
            return false;
        if(m_type == QLuaScriptProgram::ByteCode)
            return m_byteCode == other.m_byteCode;
        return m_text == other.m_text;
    }
};

QLuaScriptProgram::QLuaScriptProgram()
{
}

QLuaScriptProgram::QLuaScriptProgram(const QString& sourceCode, const QString& fileName)
    : d(new QLuaScriptProgramData)
{
    d->m_text = sourceCode;
    d->m_fileName = fileName;
    d->m_type = TextScript;
}

QLuaScriptProgram::QLuaScriptProgram(const QByteArray& program, const QString& fileName)
    : d(new QLuaScriptProgramData)
{
    if(!program.startsWith(LUA_SIGNATURE))
    {
        d->m_text = QTextCodec::codecForLocale()->toUnicode(program);
        d->m_fileName = fileName;
        d->m_type = TextScript;
    } else {
        d->m_byteCode = program;
        d->m_fileName = fileName;
        d->m_type = ByteCode;
    }
}

QLuaScriptProgram::QLuaScriptProgram(const QLuaScriptProgram& other)
    : d(other.d)
{
}

QLuaScriptProgram::~QLuaScriptProgram()
{
}

QLuaScriptProgram& QLuaScriptProgram::operator = (const QLuaScriptProgram& rhs)
{
    if (this != &rhs)
        d.operator=(rhs.d);
    return *this;
}

bool QLuaScriptProgram::isNull() const
{
    return d.data() == NULL;
}

QLuaScriptProgram::ScriptType QLuaScriptProgram::type() const
{
    return !d ? QLuaScriptProgram::TextScript : d->m_type;
}

QString QLuaScriptProgram::fileName() const
{
    return !d ? QString() : d->m_fileName;
}

QString QLuaScriptProgram::text() const
{
    return !d ? QString() : d->m_text;
}

QByteArray QLuaScriptProgram::byteCode() const
{
    return !d ? QByteArray() : d->m_byteCode;
}

bool QLuaScriptProgram::operator == (const QLuaScriptProgram& other)
{
    if(!d)
        return !other.d;
    if(!other.d)
        return false;
    return *d == *other.d;
}
